import { Injectable } from '@nestjs/common';
import { and, eq, ilike } from 'drizzle-orm';
import { BaseService, db, sysPost, type SysPost, sysUserPost } from '@nbase/db';
import { BizException } from '@nbase/nest-mods';
import type { IPaginationResponse, IPost } from '@nbase/shared';
import { CreatePostDto } from './dto/create-post.dto';
import { UpdatePostDto } from './dto/update-post.dto';
import { QueryPostDto } from './dto/query-post.dto';
import { AssignPostsDto } from './dto/assign-posts.dto';
import { toPost, toPostPage } from './post.mapper';

/**
 * 岗位服务
 */
@Injectable()
export class PostService extends BaseService<typeof sysPost> {
  constructor() {
    super(sysPost);
  }

  /**
   * 创建岗位
   */
  async createPost(createPostDto: CreatePostDto): Promise<IPost> {
    // 检查 code 是否已存在
    const isExist = await this.exists(eq(sysPost.code, createPostDto.code));
    if (isExist) {
      throw BizException.postExist();
    }

    const created = await this.create(createPostDto);
    return toPost(created as SysPost);
  }

  /**
   * 更新岗位
   */
  async updatePost(id: string, updatePostDto: UpdatePostDto): Promise<IPost> {
    // 如果更新 code，检查是否已存在
    if (updatePostDto.code) {
      const existing = await this.findOne(eq(sysPost.code, updatePostDto.code));
      if (existing && existing.id !== id) {
        throw BizException.postExist();
      }
    }

    const updated = await this.update(id, updatePostDto);
    return toPost(updated as SysPost);
  }

  /**
   * 删除岗位
   */
  async deletePost(id: string): Promise<void> {
    // 检查是否有用户使用该岗位
    const userPosts = await db
      .select()
      .from(sysUserPost)
      .where(eq(sysUserPost.postId, id))
      .limit(1);

    if (userPosts.length > 0) {
      throw BizException.postInUse();
    }

    await this.softDelete(id);
  }

  /**
   * 分页查询岗位
   */
  async paginatePosts(query: QueryPostDto): Promise<IPaginationResponse<IPost>> {

    const conditions = [];

    if (query.code) {
      conditions.push(ilike(sysPost.code, `%${query.code}%`));
    }
    if (query.name) {
      conditions.push(ilike(sysPost.name, `%${query.name}%`));
    }
    if (query.status !== undefined) {
      conditions.push(eq(sysPost.status, query.status));
    }

    const where = conditions.length > 0 ? and(...conditions) : undefined;
    const result = await this.paginate(query, where);
    return toPostPage(result as IPaginationResponse<SysPost>);
  }

  /**
   * 根据 code 查找岗位
   */
  async findByCode(code: string): Promise<IPost | null> {
    const post = (await this.findOne(eq(sysPost.code, code))) as SysPost | undefined;
    return post ? toPost(post) : null;
  }

  /**
   * 为用户分配岗位
   */
  async assignPostsToUser(userId: string, assignPostsDto: AssignPostsDto): Promise<void> {
    const currentUserId = this.getUserId();

    // 使用事务：先删除旧岗位，再添加新岗位
    await db.transaction(async (tx) => {
      await tx.delete(sysUserPost).where(eq(sysUserPost.userId, userId));

      if (assignPostsDto.postIds.length > 0) {
        const values = assignPostsDto.postIds.map((postId) => ({
          userId,
          postId,
          createdBy: currentUserId,
        }));
        await tx.insert(sysUserPost).values(values);
      }
    });
  }

  /**
   * 获取用户的岗位列表
   */
  async getUserPosts(userId: string): Promise<string[]> {
    const userPosts = await db
      .select({
        postId: sysUserPost.postId,
      })
      .from(sysUserPost)
      .where(eq(sysUserPost.userId, userId));

    return userPosts.map((up) => up.postId);
  }
}

